﻿#pragma once

#include <string>
#include <glm/glm.hpp>

namespace Hazal
{
	/// <summary>
	/// 着色器接口
	/// </summary>
	class CShader
	{
	public:
		CShader() = default;

		virtual ~CShader() {}

	public:
		virtual void Bind()const = 0;

		virtual void Unbind() const = 0;

		virtual const std::string& GetName() const = 0;

		virtual void SetMat4(const std::string& strUniform, const glm::mat4& mat4) = 0;

		virtual void SetFloat4(const std::string& strUniform, const glm::vec4& vec4) = 0;

		virtual void SetFloat3(const std::string& strUniform, const glm::vec3& vec3) = 0;

		virtual void SetFloat(const std::string& strUniform, float fValue) = 0;

		virtual void SetInt(const std::string& strUniform, int nVal) = 0;

		virtual void SetIntArray(const std::string& strUniform, const int* nVals, uint32_t unArySize) = 0;

	public:
		static Ref<CShader> Create(const std::string& strShaderName, const std::string& strVertexSrc, const std::string& strFragmentSrc);
		
		static Ref<CShader> Create(const std::string& strShaderPath);
	};

	/// <summary>
	/// 着色器库
	/// </summary>
	class CShaderLibrary
	{
	public:
		/// <summary>
		/// 添加着色器
		/// </summary>
		/// <param name="pShader"></param>
		void Add(const Ref<CShader>& pShader);

		/// <summary>
		/// 添加指定名称的着色器
		/// </summary>
		/// <param name="strShaderName">着色器名称</param>
		/// <param name="pShader">着色器路径</param>
		void Add(const std::string strShaderName, const Ref<CShader>& pShader);


		/// <summary>
		/// 加载着色器
		/// </summary>
		/// <param name="strShaderFilePath">着色器文件路径(s.t. Assets/Texture.glsl)</param>
		/// <returns></returns>
		Ref<CShader> Load(const std::string& strShaderFilePath);

		/// <summary>
		/// 加载着色器
		/// </summary>
		/// <param name="strShaderName">着色器名称</param>
		/// <param name="strShaderFilePath">着色器文件路径(s.t. Assets/Texture.glsl)</param>
		/// <returns></returns>
		Ref<CShader> Load(const std::string& strShaderName, const std::string& strShaderFilePath);

		/// <summary>
		/// 获取着色器
		/// </summary>
		/// <param name="strShaderName"></param>
		/// <returns></returns>
		Ref<CShader> Get(const std::string& strShaderName);

		/// <summary>
		/// 查找着色器是否存在
		/// </summary>
		/// <param name="strShaderName"></param>
		/// <returns></returns>
		bool Exists(const std::string& strShaderName) const;

	private:
		std::unordered_map<std::string, Ref<CShader>> m_mapShaders;
	};
}
